package com.ren.service.core.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.excel.EasyExcel;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.ren.common.exception.BusinessException;
import com.ren.common.result.ResponseEnum;
import com.ren.service.core.handler.excel.ExcelDictBOListener;
import com.ren.service.core.mapper.DictMapper;
import com.ren.service.core.model.bo.ExcelDictBO;
import com.ren.service.core.model.po.DictPO;
import com.ren.service.core.model.vo.DictVO;
import com.ren.service.core.service.IDictService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author RenGaoshuai
 * @date 2023/8/7 17:14
 * @description
 */
@Service
@Slf4j
public class DictServiceImpl implements IDictService {

    @Autowired
    private DictMapper dictMapper;
    @Autowired
    private RedisTemplate redisTemplate;

    @Override
    public List<DictVO> listByParentId(Long parentId) {
        //先查询redis中是否存在数据列表
        try {
            List<DictVO> redisCacheList = (List<DictVO>) redisTemplate.opsForValue().get("srb:core:dictList:" + parentId);
            if (redisCacheList != null) {
                log.info("从redis中取值");
                return redisCacheList;
            }
        } catch (Exception e) {
            log.error("redis服务器异常：" + ExceptionUtils.getStackTrace(e));//此处不抛出异常，继续执行后面的代码
        }

        log.info("从数据库中取值");
        List<DictPO> dictList = dictMapper.selectList(new LambdaQueryWrapper<DictPO>().eq(DictPO::getParentId, parentId));
        return dictList.stream().map(dict -> {
            boolean hasChildren = this.hasChildren(dict.getId());
            DictVO dictVO = BeanUtil.copyProperties(dict, DictVO.class);
            dictVO.setHasChildren(hasChildren);
            return dictVO;
        }).collect(Collectors.toList());
    }

    /**
     * 该节点是否有子节点
     *
     * @param id
     * @return
     */
    private boolean hasChildren(Long id) {
        Integer childrenCount = dictMapper.selectCount(new LambdaQueryWrapper<DictPO>().eq(DictPO::getParentId, id));
        return childrenCount > 0;
    }

    @Override
    public List<DictVO> list() {
        List<DictPO> dictPOS = dictMapper.selectList(null);
        return BeanUtil.copyToList(dictPOS, DictVO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void importData(InputStream inputStream) {
        EasyExcel.read(inputStream, ExcelDictBO.class, new ExcelDictBOListener(dictMapper)).sheet().doRead();
        log.info("importData finished");
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public String exportData(HttpServletResponse response) {
        try {
            response.setContentType("application/vnd.ms-excel");
            response.setCharacterEncoding("utf-8");
            String fileName = URLEncoder.encode("mydict", "UTF-8").replaceAll("\\+", "%20");
            response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

            List<ExcelDictBO> excelDictBOS = BeanUtil.copyToList(list(), ExcelDictBO.class);
            EasyExcel.write(response.getOutputStream(), ExcelDictBO.class)
                    .sheet("数据字典")
                    .doWrite(excelDictBOS);

            return fileName;
        } catch (IOException e) {
            throw new BusinessException(ResponseEnum.EXPORT_DATA_ERROR);
        }


    }
}
